﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WinFormsApp.socks;
public class T {

    public static byte[] En0(byte[] data) {
        byte mix = (byte)Environment.TickCount64;
        byte[] ret = new byte[data.Length + 1];
        ret[0] = mix;
        for (int i = 1; i < ret.Length; i++) {
            ret[i] = data[i - 1];
        }
        int prev = (mix << 5) & 0b11100000;
        for (int i = 0; i < ret.Length; i++) {
            int v = ret[i];
            int lo = (v >> 3) & 0b11111;

            ret[i] = (byte)((prev | lo) & 0xff);
            prev = (v << 5) & 0b11100000;
        }
        ret[0] = (byte)((ret[0] & 0b11111) | prev);
        int mid = ret.Length / 2;
        byte mv = ret[mid];
        for (int i = 0; i < mid; i++) {
            ret[i] = (byte)(ret[i] ^ mv);
        }

        for (int i = mid + 1; i < ret.Length; i++) {
            ret[i] = (byte)(ret[i] ^ mv);
        }

        return ret;
    }

    public static byte[] De0(byte[] data) {
        if (data.Length < 1) {
            return Array.Empty<byte>();
        }

        int mid = data.Length / 2;
        byte mv = data[mid];
        for (int i = 0; i < mid; i++) {
            data[i] = (byte)(data[i] ^ mv);
        }

        for (int i = mid + 1; i < data.Length; i++) {
            data[i] = (byte)(data[i] ^ mv);
        }

        int next = (data[data.Length - 1] >> 5) & 0b111;
        for (int i = data.Length - 1; i > -1; i--) {
            int v = data[i];
            int hi = v << 3 & 0b011111000;
            data[i] = (byte)((next | hi) & 0xff);
            next = (v >> 5) & 0b111;
        }
        data[data.Length - 1] = (byte)((data[data.Length - 1] & 0b011111000) | next);
        byte[] ret = new byte[data.Length - 1];
        for (int i = 1; i < data.Length; i++) {
            ret[i - 1] = data[i];
        }
        return ret;
    }

    public static void En(byte[] bytes) {
        if (bytes == null || bytes.Length < 1) {
            return;
        }

        byte h = bytes[0];
        for (int i = 0; i < bytes.Length - 1; i++) {
            bytes[i] = swap(bytes[i + 1]);
        }
        bytes[bytes.Length - 1] = swap(h);
    }

    public static void De(byte[] bytes) {
        if (bytes == null || bytes.Length < 1) {
            return;
        }

        byte h = bytes[bytes.Length - 1];
        for (int i = bytes.Length - 1; i > 0; i--) {
            bytes[i] = unswap(bytes[i - 1]);
        }
        bytes[0] = unswap(h);
    }

    /// <summary>
    /// 字节加密
    /// </summary>
    /// <param name="input">原始的字节</param>
    /// <returns>加工后的字节</returns>
    private static byte swap(byte input) {
        byte hi3 = (byte)((input >> 5) & 0b0111);
        byte lo5 = (byte)((input << 3) & 0b011111000);
        return (byte)(hi3 | lo5);
    }

    /// <summary>
    /// 字节解密
    /// </summary>
    /// <param name="input">加工后的字节</param>
    /// <returns>原始的字节</returns>
    private static byte unswap(byte input) {
        byte hi3 = (byte)((input << 5) & 0b011100000);
        byte lo5 = (byte)((input >> 3) & 0b011111);
        return (byte)(hi3 | lo5);
    }
}
